/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * An Configurer for configuring YAxis
 *
 * @author: jin Chen
 * @date: Jun 17, 2003
 * @version: $VERSION$
 */
package edu.psu.geovista.app.plot.axis;

import edu.psu.geovista.app.plot.ruler.Ruler;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import java.awt.*;




public class MTYAxis extends BasicAxis{  //MTYAxis
    private static final String uiClassID = "MTYAxisUI";

    public static final boolean DEBUG=false;
    //total size= DEFAULT_SIZE+DEFAULT_INSET
    public static final int DEFAULT_SIZE=200;
    public static final int DEFAULT_INSET=120;
    YAxis targetAxis;// the data axis being configured


    //private BasicAxisModel model;
    MTYAxisUI ui;
    public static final Color THUMB_COLOR_WEST = new Color(214,127,41);//(62,204,139);
    public static final Color THUMB_COLOR_EAST = new Color(11, 61, 163);
    //Ruler ruler;
    //PropertyChangeSupport pcs;


    public MTYAxis() {
        super(new MTYAxisModel());
        //this(Ruler.VERTICAL,new Extreme(100,0),300,"Sample Axis");

        this.initial() ;
    }


    public MTYAxis(int orient, Range dataRange, int activeSize, String axisName) {
        super(orient,new MTYAxisModel(), dataRange, activeSize, axisName);
        this.initial() ;

        //this.updateUI() ;

    }
    private void initial() {

        this.setActiveSize(DEFAULT_SIZE);  //default size

    }

    /*
    public void setActiveSize(int activeSize) {
        super.setActiveSize(activeSize);
        if(ui!=null)
        ui.setRulerLength(activeSize);
    }
    /*******************************************************************************************************
     *                GUI
     *******************************************************************************************************/
    public void paintComponent(Graphics g) {

        resetAxisLocation() ;
        super.paintComponent(g);
        if (ui!=null)  {
        //this.ui.paint(g,this);
        }
       // this.ruler.paintComponent(g);
    }

    protected  void resetAxisLocation() {
        int x=0, y=0;
        if (this.getOrient() ==edu.psu.geovista.app.plot.ruler.Ruler.VERTICAL ){
            //put the axis in the middle
             x=this.getLocation().x+this.getSize().width /2;
             //y=this.axisLocation.y;
            y=this.getLocation().y+(this.getSize().height -this.getActiveSize() )/4;  //

        }
        else if (this.getOrient() ==Ruler.HORIZONTAL ){
             //x=this.axisLocation.x;
             x=this.getLocation().x+(this.getSize().width -this.getActiveSize() )/2;  //
             y=this.getLocation().y+this.getSize().height /2;

            //System.out.println(this+" Not finish implement yet");
        }
        this.getAxisLocation().x=x;
        this.getAxisLocation().y=y;
    }


    /*******************************************************************************************************
         *                UI delegate
         ******************************************************************************************************/
        public ComponentUI getUI() {
            return ui;
       }


        /**
         * Sets the UI object which implements the L&F for this component.
         *
         * @param ui the YAxisPainter L&F object
         */
        public void setUI(MTYAxisUI ui) {
            super.setUI(ui);
            this.ui = ui;
        }

        /**
         * Resets the UI property to a value from the current look and feel.
         *
         * @see JComponent#updateUI
         */
        public void updateUI() {
            //updateLabelUIs();
                setUI(new MTYAxisUI(this));
              //setUI((MTYAxisUI)UIManager.getUI(this));
        }

        /**
         * Returns the name of the L&F class that renders this component.
         *
         * @return "YAxisPainter"
         * @see JComponent#getUIClassID
         * @see UIDefaults#getUI
         */
        public String getUIClassID() {
            return uiClassID;
        }

    /*******************************************************************************************************
     *                properties
     *******************************************************************************************************/
     public void setTickRange(Range tickRange) {
        super.setTickRange(tickRange);
        tryUpdateTargetRanges();

    }

    /**
     *  prevent handlers from being out of sight
     */
    private void tryUpdateTargetRanges(){
        Range showRange=getTargetAxisShowRange() ;  //control line display range of axis being configured
            Range tickRange=getTargetAxisTickRange() ; //the tick range of axis being configured

            Range cfgTickRange=getTickRange() ;
            float showMin=Math.max(cfgTickRange.getMin() ,showRange.getMin() );
            float showMax=Math.min(cfgTickRange.getMax() ,showRange.getMax() );

            float tickMin=Math.max(cfgTickRange.getMin() ,tickRange.getMin() );
            float tickMax=Math.min(cfgTickRange.getMax() ,tickRange.getMax() );

            this.setTargetAxisTickRange(new Range(tickMax,tickMin));
            this.setTargetAxisShowRange(new Range(showMax,showMin));
    }


    public void setTargetAxisShowRange(Range targetAxisShowRange) {
        MTYAxisModel model=(MTYAxisModel)this.getModel() ;
        model.setTargetAxisShowRange(targetAxisShowRange);
        this.adjustDataRange(targetAxisShowRange);
        if (this.targetAxis !=null){
             this.targetAxis.setShowRange(targetAxisShowRange);
             //Must inside if(){}, thus changing configuree axis won't fire  MTYAxis.PShowRange event
             //pcs.firePropertyChange(PShowRange,null,targetAxisShowRange);
            this.firePropertyChange(PShowRange,null,targetAxisShowRange);
        }

    }

    public Range getTargetAxisShowRange() {
        MTYAxisModel model=(MTYAxisModel)this.getModel() ;
        return model.getTargetAxisShowRange() ;
        //return this.targetAxisShowRange ;
    }


    public void setTargetAxisTickRange(Range targetAxisTickRange) {
        //JOptionPane.showMessageDialog(this, "Are u sure?");
        //askIfZoomIn(targetAxisTickRange);
        MTYAxisModel model=(MTYAxisModel)this.getModel() ;
        this.adjustDataRange(targetAxisTickRange);
        model.setTargetAxisTickRange( targetAxisTickRange);
        if(this.targetAxis !=null){
            this.targetAxis.setTickRange(targetAxisTickRange);
            //Must inside if(){}, thus changing configuree axis won't fire  MTYAxis.PTickRange event
            //pcs.firePropertyChange(PTickRange,null,targetAxisTickRange);
            this.firePropertyChange(PTickRange,null,targetAxisTickRange);
        }




    }


  



    /**
     * make sure handler won't disappear
     * @param range
     */
    private void adjustDataRange(Range range){
         Range cfgTickRange=getTickRange() ;
         float tmin=Math.min(cfgTickRange.getMin(),range.getMin() );
         float tmax=Math.max(cfgTickRange.getMax(),range.getMax() );

         super.setTickRange(new Range(tmax,tmin));

    }
     public Range getTargetAxisTickRange() {
        MTYAxisModel model=(MTYAxisModel)this.getModel() ;
        return model.getTargetAxisTickRange() ;
    }

    /*
     public void setRange(Extreme range, float max, float min) {
        this.getModel().setRange(range,max,min);
     }       */
    /*
    private void setTargetAxisRange(Extreme range){
        YAxis taxis=this.getTargetAxis() ;
        if (taxis!=null){

        }
    } */

    /*public void setRuler(Ruler ruler) {
        this.ruler = ruler;
    }

    public Ruler getRuler() {
        return ruler;
    }*/
    /*public YAxis getTargetAxis() {
        return this.targetAxis;
    }*/

    public void setTargetAxis(YAxis axis) {
        this.targetAxis =null;//MUST: clear previous target axis
        this.setDataRange(axis.getDataRange() );
 //       Extreme dr=this.getDataRange() ;

        this.setTickRange(this.getDataRange() );  //aug 30
        //this.setTickRange(axis.get );
        this.setTargetAxisTickRange(axis.getTickRange());
        this.setTargetAxisShowRange(axis.getShowRange() );
       /*//dp{
       if (DEBUG){
           System.out.println("Targetaxis.getTickRange()"+axis.getTickRange());
           System.out.println("Targetaxis.getShowRange() "+axis.getShowRange() );
       }//dp}*/
        this.setName(axis.getName() );
        this.targetAxis =axis;


    }
     /*
    public BasicAxisModel getModel(){
        if(!(this.model instanceof MTYAxisModel)){
            this.model=new MTYAxisModel();
        }
        return this.model;
    }     */

    public void setModel(BasicAxisModel model){
        this.model =model;
    }

    public void setActiveSize(int len) {
        super.setActiveSize(len);
        int ts=len+DEFAULT_INSET;//total size
        this.setPreferredSize(new Dimension(ts,ts));
    }

    /*public void addPropertyChangeListener(PropertyChangeListener l) {
        pcs.addPropertyChangeListener(l);
    }
    public void removePropertyChangeListener(PropertyChangeListener l) {
        pcs.removePropertyChangeListener(l);
    }

*/


}

